package com.boot.security.server.controller;

import java.io.*;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.boot.security.server.annotation.LogAnnotation;
import com.boot.security.server.dao.FileInfoDao;
import com.boot.security.server.dto.LayuiFile;
import com.boot.security.server.dto.LayuiFile.LayuiFileData;
import com.boot.security.server.model.FileInfo;
import com.boot.security.server.page.table.PageTableHandler;
import com.boot.security.server.page.table.PageTableHandler.CountHandler;
import com.boot.security.server.page.table.PageTableHandler.ListHandler;
import com.boot.security.server.page.table.PageTableRequest;
import com.boot.security.server.page.table.PageTableResponse;
import com.boot.security.server.service.FileService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import javax.servlet.http.HttpServletResponse;

@Api(tags = "文件")
@RestController
@RequestMapping("/files")
public class FileController {

  @Autowired
  private FileService fileService;
  @Autowired
  private FileInfoDao fileInfoDao;

  @LogAnnotation
  @PostMapping
  @ApiOperation(value = "文件上传")
  public FileInfo uploadFile(MultipartFile file) throws IOException {
    return fileService.save(file);
  }

  /**
   * layui富文本文件自定义上传
   *
   * @param file
   * @param domain
   * @return
   * @throws IOException
   */
  @LogAnnotation
  @PostMapping("/layui")
  @ApiOperation(value = "layui富文本文件自定义上传")
  public LayuiFile uploadLayuiFile(MultipartFile file, String domain) throws IOException {
    FileInfo fileInfo = fileService.save(file);

    LayuiFile layuiFile = new LayuiFile();
    layuiFile.setCode(0);
    LayuiFileData data = new LayuiFileData();
    layuiFile.setData(data);
    data.setSrc(domain + "/statics" + fileInfo.getUrl());
    data.setTitle(file.getOriginalFilename());

    return layuiFile;
  }

  @GetMapping
  @ApiOperation(value = "文件查询")
  @PreAuthorize("hasAuthority('sys:file:query')")
  public PageTableResponse listFiles(PageTableRequest request) {
    return new PageTableHandler(new CountHandler() {

      @Override
      public int count(PageTableRequest request) {
        return fileInfoDao.count(request.getParams());
      }
    }, new ListHandler() {

      @Override
      public List<FileInfo> list(PageTableRequest request) {
        List<FileInfo> list = fileInfoDao.list(request.getParams(), request.getOffset(), request.getLimit());
        return list;
      }
    }).handle(request);
  }

  @LogAnnotation
  @DeleteMapping("/{id}")
  @ApiOperation(value = "文件删除")
  @PreAuthorize("hasAuthority('sys:file:del')")
  public void delete(@PathVariable String id) {
    fileService.delete(id);
  }

  @LogAnnotation
  @ApiOperation(value = "文件下载")
	@PreAuthorize("hasAuthority('sys:file:download')")
  @GetMapping("/download")
  public String downLoad(HttpServletResponse response, @RequestParam String filePath, String origName) throws Exception{
    File file = new File(filePath);
    if (file.exists()) { //判断文件父目录是否存在
      response.setContentType("application/force-download");
      origName = new String(origName.getBytes("GB2312"),"ISO-8859-1") + filePath.substring(filePath.lastIndexOf("."));
      response.setHeader("Content-Disposition", "attachment;fileName=" + origName);
      byte[] buffer = new byte[1024];
      FileInputStream fis = null; //文件输入流
      BufferedInputStream bis = null;
      OutputStream os = null; //输出流
      try {
        os = response.getOutputStream();
        fis = new FileInputStream(file);
        bis = new BufferedInputStream(fis);
        int i = bis.read(buffer);
        while (i != -1) {
          os.write(buffer, 0, i);
          i = bis.read(buffer);
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        if (bis != null) {
          try {
            bis.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        if (fis != null) {
          try {
            fis.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    }
    return null;
  }
}